#include "..\..\Header\Graphics\fwShader.h"

char* ShaderSupport::ReadShader(char * fileName)
{
	char * shaderSrc = NULL;
	char * outPut = NULL;

	FILE* pf = fopen(fileName, "rb");
	if (!pf)
	{
		LOGE("Can't open %s file\n", fileName);
		return NULL;
	}

	fseek(pf, 0, SEEK_END);
	long size = ftell(pf);
	fseek(pf, 0, SEEK_SET);

	shaderSrc = new char[size + 1];
	fread(shaderSrc, sizeof(char), size, pf);
	shaderSrc[size] = 0;

	return shaderSrc;
}

GLuint ShaderSupport::LoadShader(GLenum type, char * shaderSrc)
{
	GLuint shader;
	GLint compiled;

	//Create new shader
	shader = glCreateShader(type);
	if (shader == 0)
	{
		LOGE("Can't create shader\n");
		return 0;
	}

	glShaderSource(shader, 1, (const char **)&shaderSrc, NULL);

	glCompileShader(shader);

	glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
	if (!compiled) //If compile shader fail
	{
		GLint infoLen = 0;

		glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
		if (infoLen > 1)
		{
			char* infoLog = new char[infoLen];

			glGetShaderInfoLog(shader, infoLen, NULL, infoLog);
			LOGE("Error compiling shader: %s", infoLog);
			SAFE_DEL_ARRAY(infoLog);
		}
		glDeleteShader(shader);
		return 0;
	}

	return shader;
}

GLuint ShaderSupport::LoadProgram(GLuint vertexShader, GLuint fragmentShader)
{
	GLuint programObject;
	GLint linked;
	GLenum err;

	// Create the program object
	programObject = glCreateProgram();

	if (programObject == 0)
	{
		LOGE("Can't create program\n");
		return 0;
	}

	glAttachShader(programObject, vertexShader);
	glAttachShader(programObject, fragmentShader);
	err = glGetError();

	// Link the program
	glLinkProgram(programObject);
	err = glGetError();

	// Check the link status
	glGetProgramiv(programObject, GL_LINK_STATUS, &linked);
	err = glGetError();

	if (!linked)
	{
		GLint infoLen = 0;
		glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &infoLen);
		if (infoLen > 1)
		{
			char* infoLog = new char[sizeof(char) * infoLen];
			glGetProgramInfoLog(programObject, infoLen, NULL, infoLog);
			LOGI(infoLog);
			delete infoLog;
		}

		glDeleteProgram(programObject);
		return 0;
	}

	return programObject;
}